package com.example.archive.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.archive.entity.Archive;
import com.example.archive.mapper.ArchiveMapper;
import com.example.archive.mapper.UserMapper;
import com.example.archive.entity.User;
import com.example.archive.service.ArchiveService;
import com.example.archive.util.PageParam;
import com.example.archive.util.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Date;

@Service
public class ArchiveServiceImpl extends ServiceImpl<ArchiveMapper, Archive> implements ArchiveService {

    private static final Logger logger = LoggerFactory.getLogger(ArchiveServiceImpl.class);

    @Autowired
    private ArchiveMapper archiveMapper;
    
    @Autowired
    private UserMapper userMapper;

    @Override
    public Result<Boolean> addArchive(Archive archive) {
        if (archive.getTitle() == null || archive.getTitle().isEmpty()) {
            return Result.fail(400, "档案标题不能为空");
        }
        if (archive.getSecurityLevel() == null || archive.getSecurityLevel().isEmpty()) {
            return Result.fail(400, "保密等级不能为空");
        }

        // Set creation and update timestamps
        archive.setCreatedAt(new Date());
        archive.setUpdatedAt(new Date());
        archive.setReceiptTime(new Date()); // Set receipt time upon creation
        archive.setStatus("active"); // Default status

        // You might want to get the current logged-in user's ID for creatorId and lastModifiedBy
        // For now, let's assume a placeholder or that it will be set by a security context later.
        // archive.setCreatorId(...);
        // archive.setLastModifiedBy(...);

        int insert = archiveMapper.insert(archive);
        logger.info("addArchive: Insert result for archive title '{}': {}", archive.getTitle(), insert);
        return insert > 0 ? Result.success(true) : Result.fail(500, "添加档案失败");
    }

    @Override
    public Result<IPage<Archive>> listArchives(PageParam pageParam, Integer userId) {
        logger.info("listArchives: pageNum={}, pageSize={}, search={}, userId={}", 
                    pageParam.getPageNum(), pageParam.getPageSize(), pageParam.getSearch(), userId);

        Page<Archive> page = new Page<>(pageParam.getPageNum(), pageParam.getPageSize());
        QueryWrapper<Archive> queryWrapper = new QueryWrapper<>();

        if (pageParam.getSearch() != null && !pageParam.getSearch().isEmpty()) {
            queryWrapper.like("title", pageParam.getSearch())
                        .or().like("archive_type", pageParam.getSearch())
                        .or().like("physical_location", pageParam.getSearch());
        }

        // 基于可见范围的过滤
        if (userId != null) {
            queryWrapper.and(wrapper -> wrapper.eq("visible_scope", "all")
                                             .or().apply("FIND_IN_SET({0}, visible_scope)", userId));
        } else {
            // 如果userId是null（如未登录），只显示可见范围为'all'的档案
            queryWrapper.eq("visible_scope", "all");
        }

        // 根据用户角色和保密等级进行权限控制
        if (userId != null) {
            try {
                User user = userMapper.selectById(userId);
                if (user != null) {
                    String userRole = user.getRole();
                    
                    switch (userRole) {
                        case "企业领导":
                            // 企业领导可以查看所有档案，无需额外过滤
                            break;
                            
                        case "档案管理员":
                            // 档案管理员可以查看除绝密外的所有档案
                            queryWrapper.and(wrapper -> wrapper.ne("security_level", "绝密"));
                            break;
                            
                        case "普通员工":
                            // 普通员工只能查看公开和内部档案，以及已批准的受限档案申请
                            queryWrapper.and(wrapper -> {
                                wrapper.in("security_level", "公开", "内部")
                                       .or().exists("SELECT 1 FROM restricted_archive_requests r " +
                                                   "WHERE r.archive_id = archives.archive_id " +
                                                   "AND r.user_id = " + userId + " " +
                                                   "AND r.approval_status = 'approved'");
                            });
                            break;
                            
                        default:
                            // 未知角色，只显示公开档案
                            queryWrapper.and(wrapper -> wrapper.eq("security_level", "公开"));
                            break;
                    }
                }
            } catch (Exception e) {
                logger.error("获取用户角色失败，用户ID: {}", userId, e);
                // 如果获取用户角色失败，只显示公开档案
                queryWrapper.and(wrapper -> wrapper.eq("security_level", "公开"));
            }
        } else {
            // 未登录用户只能查看公开档案
            queryWrapper.and(wrapper -> wrapper.eq("security_level", "公开"));
        }

        IPage<Archive> archiveIPage = archiveMapper.selectPage(page, queryWrapper);
        logger.info("listArchives: Retrieved {} records.", archiveIPage.getRecords().size());
        return Result.success(archiveIPage);
    }

    @Override
    public Result<Boolean> updateArchive(Archive archive) {
        if (archive.getArchiveId() == null) {
            return Result.fail(400, "档案ID不能为空");
        }

        // Set update timestamp and last modified by (assuming it will be set by security context)
        archive.setUpdatedAt(new Date());
        // archive.setLastModifiedBy(...); // To be set by security context later

        int update = archiveMapper.updateById(archive);
        return update > 0 ? Result.success(true) : Result.fail(500, "更新档案失败");
    }

    @Override
    public Result<Boolean> deleteArchive(Integer archiveId) {
        if (archiveId == null) {
            return Result.fail(400, "档案ID不能为空");
        }
        int delete = archiveMapper.deleteById(archiveId);
        return delete > 0 ? Result.success(true) : Result.fail(500, "删除档案失败");
    }

    @Override
    public boolean canUserAccessArchive(Integer userId, Archive archive) {
        if (userId == null || archive == null) {
            return false;
        }

        try {
            // 获取用户信息
            User user = userMapper.selectById(userId);
            if (user == null) {
                logger.warn("用户不存在，ID: {}", userId);
                return false;
            }

            String userRole = user.getRole();
            String archiveSecurityLevel = archive.getSecurityLevel();
            String visibleScope = archive.getVisibleScope();

            // 检查可见范围
            if (!"all".equals(visibleScope)) {
                // 如果不是对所有人可见，检查用户是否在可见范围内
                if (!visibleScope.contains(userId.toString())) {
                    logger.debug("用户 {} 不在档案 {} 的可见范围内", userId, archive.getArchiveId());
                    return false;
                }
            }

            // 根据用户角色和档案密级进行权限判断
            switch (userRole) {
                case "企业领导":
                    // 企业领导可以访问所有档案
                    return true;
                    
                case "档案管理员":
                    // 档案管理员可以访问除绝密外的所有档案
                    return !"绝密".equals(archiveSecurityLevel);
                    
                case "普通员工":
                    // 普通员工只能访问公开和内部档案
                    return "公开".equals(archiveSecurityLevel) || "内部".equals(archiveSecurityLevel);
                    
                default:
                    logger.warn("未知用户角色: {}", userRole);
                    return false;
            }
            
        } catch (Exception e) {
            logger.error("权限验证失败", e);
            return false;
        }
    }

    @Override
    public Result<IPage<Archive>> listPersonalArchives(PageParam pageParam, Integer userId) {
        logger.info("listPersonalArchives: pageNum={}, pageSize={}, search={}, userId={}", 
                    pageParam.getPageNum(), pageParam.getPageSize(), pageParam.getSearch(), userId);

        Page<Archive> page = new Page<>(pageParam.getPageNum(), pageParam.getPageSize());
        QueryWrapper<Archive> queryWrapper = new QueryWrapper<>();

        // 只显示该用户创建的档案或者可见范围包含该用户的档案
        queryWrapper.and(wrapper -> wrapper.eq("creator_id", userId)
                                          .or().eq("visible_scope", "all")
                                          .or().apply("FIND_IN_SET({0}, visible_scope)", userId));

        if (pageParam.getSearch() != null && !pageParam.getSearch().isEmpty()) {
            queryWrapper.and(wrapper -> wrapper.like("title", pageParam.getSearch())
                                               .or().like("archive_type", pageParam.getSearch())
                                               .or().like("ocr_content", pageParam.getSearch()));
        }

        IPage<Archive> archiveIPage = archiveMapper.selectPage(page, queryWrapper);
        logger.info("listPersonalArchives: Retrieved {} records for user {}.", archiveIPage.getRecords().size(), userId);
        return Result.success(archiveIPage);
    }
} 